package com.lyk.swap;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class WorkdayCalc implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 4910761566022804978L;

	@SuppressWarnings("deprecation")
	public static List<int[]> workdayCalc(Date start, Date end,
			Calendar calendar) {
		List<int[]> result = new ArrayList<int[]>();
		calendar.setTime(start);
		set3WorkdayBefore25(calendar);
		Date date = calendar.getTime();
		int temp[];
		if (start.before(date)) {
			if (end.before(date)) {
				temp = new int[1];
				temp[0] = calcWorkdayInMonth(start, end);
				result.add(temp);
			} else {
				temp = new int[2];
				temp[0] = calcWorkdayInMonth(start, date) - 1;
				temp[1] = calendar.get(Calendar.DATE);
				result.add(temp);
				if (end.getYear() == date.getYear()
						&& end.getMonth() == date.getMonth()) {
					temp = new int[1];
					temp[0] = calcWorkdayInMonth(date, end);
					result.add(temp);
				} else {
					int remain = calcWorkdayInMonth(
							date,
							new Date(date.getYear(), date.getMonth(), calendar
									.getActualMaximum(Calendar.DATE)));
					calendar.set(Calendar.MONTH, date.getMonth() + 1);
					set3WorkdayBefore25(calendar);
					date = calendar.getTime();
					while (!end.before(date)) {
						temp = new int[2];
						temp[0] = remain
								+ calcWorkdayInMonth(new Date(date.getYear(),
										date.getMonth(), 1), date) - 1;
						temp[1] = date.getDate();
						result.add(temp);
						remain = calcWorkdayInMonth(
								date,
								new Date(
										date.getYear(),
										date.getMonth(),
										calendar.getActualMaximum(Calendar.DATE)));
						calendar.set(Calendar.MONTH, date.getMonth() + 1);
						set3WorkdayBefore25(calendar);
						date = calendar.getTime();
					}
					calendar.setTime(end);
					set3WorkdayBefore25(calendar);
					temp = new int[1];
					if (end.after(calendar.getTime())) {
						calendar.set(Calendar.DATE,
								calendar.getActualMaximum(Calendar.DATE));
						temp[0] = remain
								- calcWorkdayInMonth(end, calendar.getTime())
								+ 1;
					} else {
						calendar.set(Calendar.DATE, 1);
						temp[0] = remain
								+ calcWorkdayInMonth(calendar.getTime(), end);
					}
					result.add(temp);
				}
			}
		} else {
			temp = new int[2];
			temp[0] = 0;
			temp[1] = date.getDate();
			result.add(temp);
			if (end.getYear() == date.getYear()
					&& end.getMonth() == date.getMonth()) {
				temp = new int[1];
				temp[0] = calcWorkdayInMonth(start, end);
				result.add(temp);
			} else {
				int remain = calcWorkdayInMonth(
						start,
						new Date(date.getYear(), date.getMonth(), calendar
								.getActualMaximum(Calendar.DATE)));
				calendar.set(Calendar.MONTH, date.getMonth() + 1);
				set3WorkdayBefore25(calendar);
				date = calendar.getTime();
				while (!end.before(date)) {
					temp = new int[2];
					temp[0] = remain
							+ calcWorkdayInMonth(
									new Date(date.getYear(), date.getMonth(), 1),
									date) - 1;
					temp[1] = date.getDate();
					result.add(temp);
					remain = calcWorkdayInMonth(
							date,
							new Date(date.getYear(), date.getMonth(), calendar
									.getActualMaximum(Calendar.DATE)));
					calendar.set(Calendar.MONTH, date.getMonth() + 1);
					set3WorkdayBefore25(calendar);
					date = calendar.getTime();
				}
				calendar.setTime(end);
				set3WorkdayBefore25(calendar);
				temp = new int[1];
				if (end.after(calendar.getTime())) {
					calendar.set(Calendar.DATE,
							calendar.getActualMaximum(Calendar.DATE));
					temp[0] = remain
							- calcWorkdayInMonth(end, calendar.getTime()) + 1;
				} else {
					calendar.set(Calendar.DATE, 1);
					temp[0] = remain
							+ calcWorkdayInMonth(calendar.getTime(), end);
				}
				result.add(temp);
			}
		}
		return result;
	}

	private static int calcWorkdayInMonth(Date start, Date end) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(start);
		int i = 0, dayOfWeek;
		while (!calendar.getTime().after(end)) {
			dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
			if (dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY) {
				i++;
			}
			calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
		}
		return i;
	}

	public static int set3WorkdayBefore25(Calendar calendar) {
		calendar.set(Calendar.DATE, 25);
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
		while (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) {
			calendar.roll(Calendar.DATE, false);
			dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
		}
		for (int i = 1; i < 3; i++) {
			calendar.roll(Calendar.DATE, false);
			dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
			while (dayOfWeek == Calendar.SATURDAY
					|| dayOfWeek == Calendar.SUNDAY) {
				calendar.roll(Calendar.DATE, false);
				dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
			}
		}
		return calendar.get(Calendar.DATE);
	}
}
